﻿using BattleFury.Data;
using BattleFury.Lib.Bots;
using BattleFury.Lib.Collections;
using BattleFury.Lib.Maps;
using BattleFury.Lib.Network;
using BattleFury.Lib.Players;
using BattleFury.Lib.ServerPlayer;
using BattleFury.Lib.Time;
using BattleFuryGameEngine;
using BattleFuryGameEngine.Events;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
using System.Linq;
using BattleFury.Lib.Extensions;
using TextureCollection = BattleFury.Lib.Collections.TextureCollection;

namespace BattleFury
{
    public static class OldRenderData
    {
        private static BattleFuryGame _bfg = BattleFuryGame.Get();

        #region Settings

        public static Vector2 MapSize = new Vector2(40, 23);
        public static Vector2 TileSize = new Vector2(32, 32);

        public static Guid ClientId { get; set; }
        public static string Username { get; set; }
        public static string Host { get; set; }
        public static int Port { get; set; }

        public static List<string> Errors = new List<string>();

        #endregion

        #region Collections

        public static TextureCollection Textures = new TextureCollection();
        public static TilesetCollection Tilesets = new TilesetCollection();
        public static FontCollection Fonts = new FontCollection();
        public static PlayerCollection Players;
        public static BotCollection Bots;

        #endregion

        #region World

        public static BattleFuryWorld World { get; set; }
        public static TileMap Map { get; set; }

        #endregion

        #region Methods

        private static int newPlayerID = 0;
        public static void LoadFromConfig(ContentManager content)
        {
            if (RenderData.Config == null)
            {
                Errors.Add("Configuration failed to load.");
                Log.Append("Configuration failed to load.");
                return;
            }

            ClientConfiguration config = RenderData.Config;
            Texture2D characterTexture = Textures.Add("Character001", content.Load<Texture2D>(".\\gfx\\Characters\\Character001"));
            _bfg.PlayerAdded += _bfg_PlayerAdded;
            _bfg.PlayerPositionUpdate += _bfg_PlayerPositionUpdate;
            _bfg.PlayerMovementUpdate += _bfg_PlayerMovementUpdate;
            if (!config.IsSpectator)
            {
                newPlayerID++;
                Player player = new Player(newPlayerID);
                player.Texture = characterTexture;
                player.Size = new Vector2(32f, 32f);
                player.MovementChanged += GenericPlayer_MovementChanged;
                Players.Add(newPlayerID, player);

                _bfg.AddPlayer(newPlayerID);
            }

            foreach (var botConfig in config.Bots)
            {
                newPlayerID++;

                Bot bot = BotLoader.Load(botConfig.Path, botConfig.FullName, newPlayerID);
                bot.MovementChanged += GenericPlayer_MovementChanged;
                bot.GetVisiblePlayersHandler = GetVisiblePlayerMethod;
                Bots.Add(newPlayerID, bot);


                _bfg.AddPlayer(newPlayerID);
            }
        }
        static List<GenericPlayer> GetVisiblePlayerMethod(GenericPlayer currentPlayer)
        {
            int visibility = 300;
            List<GenericPlayer> l = new List<GenericPlayer>();
            for (int i = 0; i < Players.Count; i++)
            {
                if (Players[i].Id != currentPlayer.Id)
                    if (Players[i].Position.Distance(currentPlayer.Position) < visibility)
                        l.Add(Players[i]);
            }
            return l;
        }
        static void GenericPlayer_MovementChanged(GenericPlayer player, MovementChangedEventArge e)
        {
            _bfg.Networking_ReceivePacket(e.MovementPacket);
        }

        static void _bfg_PlayerMovementUpdate(object sender, PlayerAddedEventArgs e)
        {
            GenericPlayer gp;
            if (!GetGenericPlayer(e, out gp)) { return; }
            gp.CurrentMovement = e.CurrentMovement;
        }

        static void _bfg_PlayerPositionUpdate(object sender, BattleFuryGameEngine.Events.PlayerAddedEventArgs e)
        {
            GenericPlayer gp;
            if (!GetGenericPlayer(e, out gp)) { return; }
            gp.Position = e.Position;
        }


        static void _bfg_PlayerAdded(object sender, BattleFuryGameEngine.Events.PlayerAddedEventArgs e)
        {
            GenericPlayer gp;
            if (!GetGenericPlayer(e, out gp)) { return; }
            gp.Position = e.Position;
            //b.Texture = e.Texture;
            gp.Size = e.Size;
        }

        private static bool GetGenericPlayer(PlayerAddedEventArgs e, out GenericPlayer gp)
        {
            gp = null;
            if (Players.ContainsKey(e.PlayerId))
                gp = Players[e.PlayerId];
            else if (Bots.ContainsKey(e.PlayerId))
                gp = Bots[e.PlayerId];
            else
                return false;
            return true;
        }

        #endregion

        public static void SetConfig(ClientConfiguration config)
        {
            //OldRenderData.Config = config;
            _bfg.Start();
        }


    }
}